home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
526-550
/
disk_542
/
chemnimate
/
cmtsource.lzh
/
ch14.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-08-28
|
10KB
|
343 lines
/****************************************************************
* *
* ChemNiMate to Animate Chemical Reactions *
* *
* *
* this program is written to show how molecules *
* are in 3-d and how mechanisms work. *
* *
* *
* *
*Note that this program is entirely written using integers!!! *
* *
*==============================================================*
*Vers. Date Author Comment *
*sk1 22Mar91 KvGend started working on it. *********
*sk5 24Mar91 KvGend is now able to rotate some complicated formula *
*sk9 30Mar91 KvGend Now accepts scripts. Is able to play *
* along with penicilline *
*ch3 02Apr91 KvGend Rewrote parser and put it in separate file. *
*ch6 07Apr91 KvGend Corrected bugs, now is parser able to use *
* full words as commands. *
*ch9 27Apr91 KvGend Corrected bugs, now parser skips spaces *
* at the beginning/no more GURU when a ball flies *
* out of the screen. A lot of objects added. *
*ch11 13Jun91 KvGend now loads full script in memory before executing*
* it. *
*ch12 17Jul91 KvGend Added second displaymode, added skip, improved *
* the Loop/Until. *
*ch14 28Aug91 KvGend First release (I HOPE) *
* *
* *
* *
* *
************************************************************************/
#ifdef AMIGA /* some amiga-specific stuff */
#include <exec/types.h>
#include <graphics/rastport.h>
extern struct GfxBase *gfxbase;
struct RastPort rastport;
extern struct BitMap *bitmap, *sourcebitmap;
#endif
#include "std:gonio.c" /* the provision of cos() and sin()*/
#include "uni4.h"
#include "/k/k5.h" /* to provide the linked lists */
char header[] = " ChemNiMate, to animate Chemical Structs ";
char footer[] = " © 1991 KP van Gend/R Knaapen ";
struct DisplayInfo di = /* default-values */
{
180, 125, /*middle-(x,y) */
65536, 1, /* angle,delta-angle */
0 | LINES | BALLS, /* displaymodes */
1, /* which playfield is active */
};
int volg[MXNUMB];
int array[MXNUMB][8];
FILE *infile;
extern char *tlist[]; /* the list with tokens */
extern struct ParserInfo pi;
/***********************prototypes**********/
/* in parser##.c */
extern int parser (char *, int);
/* in 2nd##.c */
extern SetUp (void);
extern SwapShow ();
extern Quit (void);
/*********************************main()***/
main (int argc, char **argv)
{
char regel[255]; /* the linebuffer (regel{Dutch}=line{Eng})*/
char *line;
int i, dummy, listnr;
HEAD_T *hoofd;
INFO_T *vel;
if (argc != 2)
{
printf ("ChemNiMate was written to animate Chemistry Structures\n© by KP van Gend & R Knaapen\nUSAGE: %s <NameOfScript>\n", argv[0]);
exit (0);
}
infile = (FILE *) fopen (argv[1], "r");
if (infile == NULL)
{
printf ("file does not exist\n");
exit (5);
}
/*****inlezen file *****/
hoofd = create ();
pi.linenr = 0;
printf ("PASS 1: (loading)\n");
while (fgets (regel, 254, infile) != NULL)
{
pi.linenr++;
line = regel;
/* remove preceding spaces/TABs */
for (; line[0] == ' ' || line[0] == 9;)
line++;
/* remove a remark */
for (i = 0; i < strlen (line); i++)
if (line[i] == ';')
{
line[i] = 10; /* replace it by a hard-return*/
line[i + 1] = 0; /* and end it up here */
}
/* correct a binary minus: [7 - 3] should be [7 _ 3] */
for (i = 0; (i < strlen (line)) && (line[i] != '\"'); i++)
if (line[i] == '-' && !ISNUM (line[i + 1]))
line[i] = '_';
/* make uppercase of all applicable stuff */
for (i = 0; i < strlen (line); i++)
{
line[i] = toupper (line[i]);
if (line[i] == '\"')
break;
}
/* find token in list*/
listnr = 0;
if (line[0] == ';' || line[0] == 10)
listnr = -1;
else
while (tlist[listnr][0])
{
dummy = tlist[listnr][0] & 0xff;
for (i = 0; tlist[listnr][i + 2] != 0; i++) /* compare two strings*/
if (tlist[listnr][i + 2] != line[i])
dummy = 0;
if (dummy != 0) /*strings are the same*/
break;
listnr++;
}
/* and save it to the linked list */
append (makeinfo (pi.linenr, listnr, line), hoofd);
} /* end-of-while(fgets( )) */
fclose (infile); /* close file*/
/*****start executing ******/
SetUp ();
printf ("PASS 2: (executing)\n");
pi.linenr = 1;
while (vel = gimmelinnr (hoofd, pi.linenr))
{
pi.linenr++;
if (vel->token == -1) /* this is an empty line*/
continue;
/* copy line to buffer*/
for (i = 0; i < strlen (vel->string); i++)
regel[i] = vel->string[i];
regel[i] = '\0';
parser (regel, vel->token);
}
/*****We're finished now...******/
Quit ();
return(0); /*nothing wrong...*/
} /*****end-of-main()*/
/**************************TextAt()************************/
TextAt (int xc, int yc, char *string)
{
MOVE (xc + LBOR, yc + UBOR);
TEXT (string);
}
/**************************LetItShow()*********************/
LetItShow (int nrframes, int start, int maxnr)
{
int teller;
/* init sort-array (name: volg) */
for (teller = start; teller <= maxnr; teller++)
volg[teller] = teller;
if (nrframes==0)
teller=0;
else
teller=1;
for (; teller <= nrframes; teller++)
{
di.angle += di.dangle; /* rotate figure, if necessary*/
if (di.modes % 16 == 0)
DrawBalls0 (start, maxnr); /* draw balls 3-d */
if (di.modes % 16 == 1)
DrawBalls1 (start, maxnr); /* draw balls 2-d (watch along y-axis)*/
COLOR (1); /*print header */
TextAt (2, 7, header);
TextAt (2, VHEIGHT - 3, footer); /*print footer */
if (nrframes!=0)
SwapShow();
}
}
/*******************************DrawBalls0(startnr,maxnr)****/
DrawBalls0 (int start, int maxnr)
{
int j, quit;
int scrx, scry;
COLOR (1); /* I just put it here */
/***** uitrekenen van de Carthesische coördinaten */
for (j = start; j <= maxnr; j++)
{
array[j] XC = Sin (di.angle + array[j] ADD, array[j] RAD);
array[j] YC = Cos (di.angle + array[j] ADD, array[j] RAD);
array[j] ZC = array[j] HEIGHT;
}
/***** (her)sorteren van de atomen op diepte (x-as) */
do
{
quit = 245; /* just a random value */
for (j = start; j < maxnr; j++)
if (array[volg[j]] XC < array[volg[j + 1]] XC)
{
quit = volg[j];
volg[j] = volg[j + 1];
volg[j + 1] = quit;
}
} while (quit != 245);
/***** van achter naar voren toe alle balletjes plaatsen */
for (quit = maxnr; quit >= start; quit--)
{
j = volg[quit];
scrx = RX (array[j] YC, array[j] XC);
scry = RY (ARR ZC, ARR XC);
if (ARR BIND == j)
PutBall (scrx, scry, array[j] KIND);
else if (ARR XC > array[ARR BIND] XC) /* draw line or ball first */
{
PleaseLine (scrx, scry, ARR BIND);
PutBall (scrx, scry, array[j] KIND);
}
else
{
PutBall (scrx, scry, array[j] KIND);
PleaseLine (scrx, scry, ARR BIND);
}
} /*end-of-for*/
} /****end-of-DrawBalls0***/
/*******************************DrawBalls1(startnr,maxnr)****/
DrawBalls1 (int start, int maxnr)
{
int j, quit;
COLOR (1); /* I just put it here */
/***** calculate Carthesian coordinates */
for (j = start; j <= maxnr; j++)
{
array[j] XC = di.mx + Cos (di.angle + array[j] ADD, array[j] RAD);
array[j] YC = di.my - Sin (di.angle + array[j] ADD, array[j] RAD);
array[j] ZC = array[j] HEIGHT;
}
/***** (re)sort van de atomen depth (x-y plane ) */
do
{
quit = 245; /* just a random value */
for (j = start; j < maxnr; j++)
if (array[volg[j]] ZC < array[volg[j + 1]] ZC)
{
quit = volg[j];
volg[j] = volg[j + 1];
volg[j + 1] = quit;
}
} while (quit != 245);
/***** put all balls, from below to up */
for (quit = maxnr; quit >= start; quit--)
{
j = volg[quit];
if (ARR BIND == j)
PutBall (array[j] XC, array[j] YC, array[j] KIND);
else if (ARR ZC < array[ARR BIND] ZC) /* draw line or ball first */
{
PleaseLine1 (ARR XC, ARR YC, ARR BIND);
PutBall (ARR XC, ARR YC, ARR KIND);
}
else
{
PutBall (ARR XC, ARR YC, ARR KIND);
PleaseLine1 (ARR XC, ARR YC, ARR BIND);
}
} /*end-of-for*/
} /****end-of-DrawBalls1()****/
/***********************************PutBall( scrx, scry,which ball)******/
PutBall (int scrx, int scry, int k)
{
if (di.modes & BALLS) /* don't draw a ball when bit is set */
if (scrx < LBOR | scrx > LBOR + VWIDTH | scry < UBOR | scry > UBOR + VHEIGHT)
pi.error = OUTSCREEN_ERR;
else
{
/* now follows the routine to put a ball with its centre at (scrx,scry)
* first the Background at that place is erased, then the ball
* is OR'ed in the bitmap.
*/
#ifdef AMIGA
BltBitMap (SBM, 32 + (k & 7) * 32, 4 * (k & (~7)), BM, scrx, scry, 31, 31, 0x20, 0xF, 0);
BltBitMap (SBM, (k & 7) * 32, 4 * (k & (~7)), BM, scrx, scry, 31, 31, 0xE0, 0xF, 0);
#endif
}
}
/*********************************PleaseLine(scrx,srcy,to whichball)******/
PleaseLine (int scrx, int scry, int nr)
{
if (di.modes & LINES)
if (scrx < LBOR | scrx > LBOR + VWIDTH | scry < UBOR | scry > UBOR + VHEIGHT)
pi.error = OUTSCREEN_ERR;
else
{
MOVE (scrx + 16, scry + 16);
LINETO (RX (array[nr] YC, array[nr] XC) + 16,
RY (array[nr] ZC, array[nr] XC) + 16);
}
}
PleaseLine1 (int scrx, int scry, int nr)
{
if (di.modes & LINES)
if (scrx < LBOR | scrx > LBOR + VWIDTH | scry < UBOR | scry > UBOR + VHEIGHT)
pi.error = OUTSCREEN_ERR;
else
{
MOVE (scrx + 16, scry + 16);
LINETO (array[nr] XC + 16, array[nr] YC + 16);
}
}